
package com.tonyodev.fetch2;

import ohos.utils.net.Uri;

import com.tonyodev.fetch2core.Extras;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.Serializable;
import java.util.Map;

/**
 * An immutable object which contains a current snapshot of all the information
 * about a specific download managed by Fetch.
 *
 * @since 2021-05-20
 */
public interface Download extends Serializable {
    /**
     * Used to identify a download. This id also matches the id of the request that started
     * the download.
     *
     * @return download id
     */
    int getId();

    /**
     * The Fetch namespace this download belongs to
     *
     * @return namespace
     */
    @NotNull
    String getNamespace();

    /**
     * The url where the file will be downloaded from.
     *
     * @return url
     */
    @NotNull
    String getUrl();

    /**
     * The file eg(/files/download.txt) where the file will be
     * downloaded to and saved on disk.
     *
     * @return file
     */
    @NotNull
    String getFile();

    /**
     * The group id this download belongs to.
     *
     * @return group
     */
    int getGroup();

    /**
     * The download Priority of this download.
     *
     * @return download Priority
     */
    @NotNull
    Priority getPriority();

    /**
     * The headers used by the downloader to send header information to
     * the server about a request.
     *
     * @return headers
     */
    @NotNull
    Map getHeaders();

    /**
     * The amount of bytes downloaded thus far and saved to the file
     *
     * @return downloaded
     */
    long getDownloaded();

    /**
     * The file size of a download in bytes. This field could return -1 if the server
     * did not readily provide the Content-Length when the connection was established
     *
     * @return size
     */
    long getTotal();

    /**
     * The current status of a download.
     *
     * @return current status
     */
    @NotNull
    Status getStatus();

    /**
     * If the download encountered an error, the download status will be Status.Failed and
     * this field will provide the specific error when possible.
     * Otherwise the default non-error value is Error.NONE.
     *
     * @return download encountered an error
     */
    @NotNull
    Error getError();

    /**
     * The network type this download is allowed to download on.
     *
     * @return network type
     */
    @NotNull
    NetworkType getNetworkType();

    /**
     * The download progress thus far eg(95 indicating 95% completed). If the total field of
     * this object has a value of -1, this field will also return -1 indicating that the server
     * did not readily provide the Content-Length and that the progress is undetermined.
     *
     * @return download progress
     */
    int getProgress();

    /**
     * The timestamp when this download was created.
     *
     * @return download was created
     */
    long getCreated();

    /**
     * The request information used to create this download.
     *
     * @return request
     */
    Request getRequest();

    /**
     * Gets a copy of this instance.
     *
     * @return copy
     */
    Download copy();

    /**
     * Gets the tag associated with this download
     *
     * @return tag
     */
    @Nullable
    String getTag();

    /**
     * Action used by Fetch when enqueuing a request and a previous request with the
     * same file is already being managed. Default EnqueueAction.REPLACE_EXISTING
     * which will replaces the existing request.
     *
     * @return enqueuing
     */
    EnqueueAction getEnqueueAction();

    /**
     * Can be used to set your own unique identifier for the request.
     *
     * @return identifier
     */
    long getIdentifier();

    /**
     * Action used by Fetch when enqueuing a request to determine if to place the new request in
     * the downloading queue immediately after enqueue to be processed with its turn arrives
     * The default value is true.
     * If true, the download will have a status of Status.QUEUED. If false, the download will have a status
     * of Status.ADDED.
     *
     * @return Action
     */
    boolean getDownloadOnEnqueue();

    /**
     * Stored custom data/ key value pairs with a request.
     * Use fetch.replaceExtras(id, extras)
     *
     * @return Stored
     */
    Extras getExtras();

    /**
     * Returns the fileUri
     *
     * @return fileUri
     */
    Uri getFileUri();

    /**
     * The estimated time in milliseconds until the download completes.
     * This field will always be -1 if the download is not currently being downloaded.
     *
     * @return milliseconds
     */
    long getEtaInMilliSeconds();

    /**
     * Average downloaded bytes per second.
     * Can return -1 to indicate that the estimated time remaining is unknown. This field will
     * always return -1 when the download is not currently being downloaded.
     *
     * @return downloaded bytes
     */
    long getDownloadedBytesPerSecond();

    /**
     * The maximum number of times Fetch will auto retry a failed download.
     * The default is 0.
     *
     * @return maximum
     */
    int getAutoRetryMaxAttempts();

    /**
     * The number of times Fetch has tried to download this request after a failed attempt.
     *
     * @return number
     */
    int getAutoRetryAttempts();
}
